home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / net / RCS / rcmd.c,v < prev    next >
Text File  |  1992-03-27  |  8KB  |  432 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  sprited:1.5.1;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     90.05.04.11.24.18;  author douglis;  state Exp;
  11. branches 1.5.1.1;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     88.07.29.16.59.41;  author ouster;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     88.07.25.13.46.28;  author ouster;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     88.07.25.11.00.58;  author ouster;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     88.06.20.09.57.15;  author ouster;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34. 1.5.1.1
  35. date     92.03.27.18.57.24;  author kupfer;  state Exp;
  36. branches ;
  37. next     ;
  38.  
  39.  
  40. desc
  41. @@
  42.  
  43.  
  44. 1.5
  45. log
  46. @tve changed rcmd to handle numeric addresses.
  47. @
  48. text
  49. @/*
  50.  * Copyright (c) 1983 Regents of the University of California.
  51.  * All rights reserved.
  52.  *
  53.  * Redistribution and use in source and binary forms are permitted
  54.  * provided that this notice is preserved and that due credit is given
  55.  * to the University of California at Berkeley. The name of the University
  56.  * may not be used to endorse or promote products derived from this
  57.  * software without specific prior written permission. This software
  58.  * is provided ``as is'' without express or implied warranty.
  59.  */
  60.  
  61. #if defined(LIBC_SCCS) && !defined(lint)
  62. static char sccsid[] = "@@(#)rcmd.c    5.16 (Berkeley) 3/7/88";
  63. #endif /* LIBC_SCCS and not lint */
  64.  
  65. #include <stdio.h>
  66. #include <ctype.h>
  67. #include <pwd.h>
  68. #include <sys/param.h>
  69. #include <sys/file.h>
  70. #include <sys/signal.h>
  71. #include <sys/socket.h>
  72. #include <sys/stat.h>
  73.  
  74. #include <netinet/in.h>
  75.  
  76. #include <netdb.h>
  77. #include <errno.h>
  78. #include <strings.h>
  79.  
  80. extern    errno;
  81. extern char *inet_ntoa();
  82.  
  83. rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
  84.     char **ahost;
  85.     u_short rport;
  86.     char *locuser, *remuser, *cmd;
  87.     int *fd2p;
  88. {
  89.     int s, timo = 1, pid;
  90.     int oldmask;
  91.     struct sockaddr_in sin, from;
  92.     char c;
  93.     int lport = IPPORT_RESERVED - 1;
  94.     struct hostent *hp;
  95.  
  96.     pid = getpid();
  97.  
  98.     sin.sin_addr.s_addr = inet_addr(*ahost);
  99.     if (sin.sin_addr.s_addr != -1) {
  100.     sin.sin_family = AF_INET;
  101.     } else {
  102.     hp = gethostbyname(*ahost);
  103.     if (hp == 0) {
  104.         fprintf(stderr, "%s: unknown host\n", *ahost);
  105.         return (-1);
  106.     }
  107.     *ahost = hp->h_name;
  108.     sin.sin_family = hp->h_addrtype;
  109.     bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  110.     }
  111.     oldmask = sigblock(sigmask(SIGURG));
  112.     for (;;) {
  113.         s = rresvport(&lport);
  114.         if (s < 0) {
  115.             if (errno == EAGAIN)
  116.                 fprintf(stderr, "socket: All ports in use\n");
  117.             else
  118.                 perror("rcmd: socket");
  119.             sigsetmask(oldmask);
  120.             return (-1);
  121.         }
  122.         fcntl(s, F_SETOWN, pid);
  123.         sin.sin_port = rport;
  124.         if (connect(s, (struct sockaddr *) &sin, sizeof (sin)) >= 0)
  125.             break;
  126.         (void) close(s);
  127.         if (errno == EADDRINUSE) {
  128.             lport--;
  129.             continue;
  130.         }
  131.         if (errno == ECONNREFUSED && timo <= 16) {
  132.             sleep(timo);
  133.             timo *= 2;
  134.             continue;
  135.         }
  136.         if (hp->h_addr_list[1] != NULL) {
  137.             int oerrno = errno;
  138.  
  139.             fprintf(stderr,
  140.                 "connect to address %s: ", inet_ntoa(sin.sin_addr));
  141.             errno = oerrno;
  142.             perror((char *) 0);
  143.             hp->h_addr_list++;
  144.             bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
  145.                 hp->h_length);
  146.             fprintf(stderr, "Trying %s...\n",
  147.                 inet_ntoa(sin.sin_addr));
  148.             continue;
  149.         }
  150.         perror(hp->h_name);
  151.         sigsetmask(oldmask);
  152.         return (-1);
  153.     }
  154.     lport--;
  155.     if (fd2p == 0) {
  156.         write(s, "", 1);
  157.         lport = 0;
  158.     } else {
  159.         char num[8];
  160.         int s2 = rresvport(&lport), s3;
  161.         int len = sizeof (from);
  162.  
  163.         if (s2 < 0)
  164.             goto bad;
  165.         listen(s2, 1);
  166.         (void) sprintf(num, "%d", lport);
  167.         if (write(s, num, strlen(num)+1) != strlen(num)+1) {
  168.             perror("write: setting up stderr");
  169.             (void) close(s2);
  170.             goto bad;
  171.         }
  172.         s3 = accept(s2, &from, &len);
  173.         (void) close(s2);
  174.         if (s3 < 0) {
  175.             perror("accept");
  176.             lport = 0;
  177.             goto bad;
  178.         }
  179.         *fd2p = s3;
  180.         from.sin_port = ntohs((u_short)from.sin_port);
  181.         if (from.sin_family != AF_INET ||
  182.             from.sin_port >= IPPORT_RESERVED) {
  183.             fprintf(stderr,
  184.                 "socket: protocol failure in circuit setup.\n");
  185.             goto bad2;
  186.         }
  187.     }
  188.     (void) write(s, locuser, strlen(locuser)+1);
  189.     (void) write(s, remuser, strlen(remuser)+1);
  190.     (void) write(s, cmd, strlen(cmd)+1);
  191.     if (read(s, &c, 1) != 1) {
  192.         perror(*ahost);
  193.         goto bad2;
  194.     }
  195.     if (c != 0) {
  196.         while (read(s, &c, 1) == 1) {
  197.             (void) write(2, &c, 1);
  198.             if (c == '\n')
  199.                 break;
  200.         }
  201.         goto bad2;
  202.     }
  203.     sigsetmask(oldmask);
  204.     return (s);
  205. bad2:
  206.     if (lport)
  207.         (void) close(*fd2p);
  208. bad:
  209.     (void) close(s);
  210.     sigsetmask(oldmask);
  211.     return (-1);
  212. }
  213.  
  214. rresvport(alport)
  215.     int *alport;
  216. {
  217.     struct sockaddr_in sin;
  218.     int s;
  219.  
  220.     sin.sin_family = AF_INET;
  221.     sin.sin_addr.s_addr = INADDR_ANY;
  222.     s = socket(AF_INET, SOCK_STREAM, 0);
  223.     if (s < 0)
  224.         return (-1);
  225.     for (;;) {
  226.         sin.sin_port = htons((u_short)*alport);
  227.         if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  228.             return (s);
  229.         if (errno != EADDRINUSE) {
  230.             (void) close(s);
  231.             return (-1);
  232.         }
  233.         (*alport)--;
  234.         if (*alport == IPPORT_RESERVED/2) {
  235.             (void) close(s);
  236.             errno = EAGAIN;        /* close */
  237.             return (-1);
  238.         }
  239.     }
  240. }
  241.  
  242. ruserok(rhost, superuser, ruser, luser)
  243.     char *rhost;
  244.     int superuser;
  245.     char *ruser, *luser;
  246. {
  247.     FILE *hostf;
  248.     char fhost[MAXHOSTNAMELEN];
  249.     int first = 1;
  250.     register char *sp, *p;
  251.     int baselen = -1;
  252.  
  253.     sp = rhost;
  254.     p = fhost;
  255.     while (*sp) {
  256.         if (*sp == '.') {
  257.             if (baselen == -1)
  258.                 baselen = sp - rhost;
  259.             *p++ = *sp++;
  260.         } else {
  261.             *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
  262.         }
  263.     }
  264.     *p = '\0';
  265.     hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
  266. again:
  267.     if (hostf) {
  268.         if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
  269.             (void) fclose(hostf);
  270.             return(0);
  271.         }
  272.         (void) fclose(hostf);
  273.     }
  274.     if (first == 1) {
  275.         struct stat sbuf;
  276.         struct passwd *pwd;
  277.         char pbuf[MAXPATHLEN];
  278.  
  279.         first = 0;
  280.         if ((pwd = getpwnam(luser)) == NULL)
  281.             return(-1);
  282.         (void)strcpy(pbuf, pwd->pw_dir);
  283.         (void)strcat(pbuf, "/.rhosts");
  284.         if ((hostf = fopen(pbuf, "r")) == NULL)
  285.             return(-1);
  286.         (void)fstat(fileno(hostf), &sbuf);
  287.         if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
  288.             fclose(hostf);
  289.             return(-1);
  290.         }
  291.         goto again;
  292.     }
  293.     return (-1);
  294. }
  295.  
  296. _validuser(hostf, rhost, luser, ruser, baselen)
  297. char *rhost, *luser, *ruser;
  298. FILE *hostf;
  299. int baselen;
  300. {
  301.     char *user;
  302.     char ahost[MAXHOSTNAMELEN];
  303.     register char *p;
  304.  
  305.     while (fgets(ahost, sizeof (ahost), hostf)) {
  306.         p = ahost;
  307.         while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
  308.             *p = isupper(*p) ? tolower(*p) : *p;
  309.             p++;
  310.         }
  311.         if (*p == ' ' || *p == '\t') {
  312.             *p++ = '\0';
  313.             while (*p == ' ' || *p == '\t')
  314.                 p++;
  315.             user = p;
  316.             while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
  317.                 p++;
  318.         } else
  319.             user = p;
  320.         *p = '\0';
  321.         if (_checkhost(rhost, ahost, baselen) &&
  322.             !strcmp(ruser, *user ? user : luser)) {
  323.             return (0);
  324.         }
  325.     }
  326.     return (-1);
  327. }
  328.  
  329. _checkhost(rhost, lhost, len)
  330. char *rhost, *lhost;
  331. int len;
  332. {
  333.     static char ldomain[MAXHOSTNAMELEN + 1];
  334.     static char *domainp = NULL;
  335.     static int nodomain = 0;
  336.     register char *cp;
  337.  
  338.     if (len == -1)
  339.         return(!strcmp(rhost, lhost));
  340.     if (strncmp(rhost, lhost, len))
  341.         return(0);
  342.     if (!strcmp(rhost, lhost))
  343.         return(1);
  344.     if (*(lhost + len) != '\0')
  345.         return(0);
  346.     if (nodomain)
  347.         return(0);
  348.     if (!domainp) {
  349.         if (gethostname(ldomain, sizeof(ldomain)) == -1) {
  350.             nodomain = 1;
  351.             return(0);
  352.         }
  353.         ldomain[MAXHOSTNAMELEN] = NULL;
  354.         if ((domainp = index(ldomain, '.')) == (char *)NULL) {
  355.             nodomain = 1;
  356.             return(0);
  357.         }
  358.         for (cp = ++domainp; *cp; ++cp)
  359.             if (isupper(*cp))
  360.                 *cp = tolower(*cp);
  361.     }
  362.     return(!strcmp(domainp, rhost + len +1));
  363. }
  364. @
  365.  
  366.  
  367. 1.5.1.1
  368. log
  369. @Initial branch for Sprite server.
  370. @
  371. text
  372. @@
  373.  
  374.  
  375. 1.4
  376. log
  377. @Lint.
  378. @
  379. text
  380. @d49 5
  381. d60 3
  382. a74 2
  383.         sin.sin_family = hp->h_addrtype;
  384.         bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
  385. @
  386.  
  387.  
  388. 1.3
  389. log
  390. @Lint.
  391. @
  392. text
  393. @d42 1
  394. a42 1
  395.     long oldmask;
  396. d70 1
  397. a70 1
  398.         if (connect(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
  399. d88 1
  400. a88 1
  401.             perror(0);
  402. d118 1
  403. a118 1
  404.         s3 = accept(s2, &from, &len, 0);
  405. d173 1
  406. a173 1
  407.         if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
  408. @
  409.  
  410.  
  411. 1.2
  412. log
  413. @Lint.
  414. @
  415. text
  416. @d43 1
  417. a43 1
  418.     struct sockaddr_in sin, sin2, from;
  419. @
  420.  
  421.  
  422. 1.1
  423. log
  424. @Initial revision
  425. @
  426. text
  427. @d30 1
  428. d33 1
  429. a33 1
  430. char    *index();
  431. @
  432.